package com.sk.bilibili.apiMapper.scanner;

import com.sk.bilibili.apiMapper.annotation.ApiMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.core.type.filter.AnnotationTypeFilter;

import java.util.Set;

/**
 * @author 邵康
 * @date 2021/8/9 16:12
 */
@Slf4j
public class ApiMapperScanner extends ClassPathBeanDefinitionScanner{

    public ApiMapperScanner(BeanDefinitionRegistry registry) {
        super(registry,false);
        addIncludeFilter(new AnnotationTypeFilter(ApiMapper.class));
    }
    @Override
    protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
        Set<BeanDefinitionHolder> definitionHolders = super.doScan(basePackages);
        handleBeanDefinitionHolder(definitionHolders);
        return definitionHolders;
    }
    private void handleBeanDefinitionHolder(Set<BeanDefinitionHolder> definitionHolders) {
        for (BeanDefinitionHolder holder:definitionHolders){
            BeanDefinition definition = holder.getBeanDefinition();
            String className = definition.getBeanClassName();
            definition.setBeanClassName("com.sk.bilibili.apiMapper.factory.ApiMapperFactoryBean");
            MutablePropertyValues values = definition.getPropertyValues();
            values.add("apiMapper",new RuntimeBeanReference("apiMapper"));
            values.add("targetClass",className);
            logger.info("ApiMapper Is Mapper:"+className);
        }
    }
    @Override
    protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
        return beanDefinition.getMetadata().isInterface()&&beanDefinition.getMetadata().isIndependent();
    }
}
